package com.ch.engine.daily.other;

import com.cronutils.model.Cron;
import com.cronutils.model.CronType;
import com.cronutils.model.definition.CronDefinitionBuilder;
import com.cronutils.model.time.ExecutionTime;
import com.cronutils.parser.CronParser;

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * corn表达式时间测算
 *
 * @author wangchunhui
 * @date 2024/10/15 17:44
 */
public class CronNextExecutionTimes {

    public static void main(String[] args) {
        String cronExpression = "0 0/1 11,12,21,22 * * ?";
        // 使用 QUARTZ 风格的解析器来解析 cron 表达式
        CronParser parser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ));
        Cron cron = parser.parse(cronExpression);

        // 获取当前时间作为起点
        ZonedDateTime now = ZonedDateTime.now();

        // 输出最近100次执行时间
        List<ZonedDateTime> nextExecutionTimes = getNextExecutionTimes(cron, now, 1000);

        // 格式化输出
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        for (ZonedDateTime dateTime : nextExecutionTimes) {
            System.out.println(dateTime.format(formatter));
        }
    }

    /**
     * 获取接下来 n 次的执行时间
     *
     * @param cron      cron 表达式对象
     * @param startTime 开始时间
     * @param count     获取多少次
     * @return 执行时间的列表
     */
    public static List<ZonedDateTime> getNextExecutionTimes(Cron cron, ZonedDateTime startTime, int count) {
        List<ZonedDateTime> nextTimes = new ArrayList<>();
        ExecutionTime executionTime = ExecutionTime.forCron(cron);

        ZonedDateTime nextTime = startTime;
        for (int i = 0; i < count; i++) {
            nextTime = executionTime.nextExecution(nextTime).orElse(null);
            if (nextTime == null) {
                break;
            }
            nextTimes.add(nextTime);
        }
        return nextTimes;
    }
}
